import { Button, NavBar, Form, Input, Toast } from 'antd-mobile'
import { InputRef } from 'antd-mobile/es/components/input'
import { useDispatch } from 'react-redux'
import { useHistory, useLocation } from 'react-router-dom'
import { login, getCode } from '@/store/actions/login'
import { AxiosError } from 'axios'
import { useEffect, useRef, useState } from 'react'

import styles from './index.module.scss'

type LoginForm = {
	mobile: string
	code: string
}

const Login = () => {
	const dispatch = useDispatch()
	const history = useHistory()

	// 注意： state 可能是不存在的，所以，类型中要明确包含不存在的情况，即 undefined
	//使用useLocation获取路由重定向传入的state
	const location = useLocation<{ from: string | undefined }>()

	//倒计时
	const [timeLeft, setTimeLeft] = useState(0)
	// 定时器 ref
	const timerRef = useRef(-1)

	// 登录
	// 默认 Form 并没有为 onFinish 指定 value 的类型，
	//因为 Form 不清楚表单中处理的是什么数据
	// 所以，需要自己根据自己的 Form 表单项来手动指定 values 的类型即可
	const onFinish = async (values: LoginForm) => {
		// console.log(values)
		try {
			await dispatch(login(values))
			//登录成功提示
			Toast.show({
				content: '登录成功',
				duration: 600,
				afterClose: () => {
					//登录完成跳转是判断state 不存在跳转到state指定页面 存在返回首页
					history.replace(location.state?.from ?? '/home/index')
				},
			})
		} catch (e) {
			// 异常
			// 如果异步操作失败了，会执行此处的错误处理
			// 对于登录功能来说，出错了，通常是请求出问题了。
			// 因此，此处将错误类型转为 AxiosError
			const error = e as AxiosError<{ message: string }>
			Toast.show({
				content: error.response?.data?.message,
				duration: 1000,
			})
		}
	}

	//动态登录按钮
	//创建form实例 手动获取Form表单校验状态
	const [form] = Form.useForm()

	//验证码功能
	//创建获取手机号的ref对象
	//注意：现在要操作的是Input组件，所以泛型参数为组件的ref类型
	const mobileRef = useRef<InputRef>(null)

	const onGetCode = () => {
		// 如何获取 手机号 文本框的值？ 通过 Form 来获取
		// 参数表示 Form.Item name 属性
		// 注意： mobile 的值有可能是 undefined，所以，在类型断言的时候，也需要明确指出 undefined
		//  如果 手机号的文本框 还没有输入过内容，那么，值为：undefined
		//  如果 手机号的文本框 输入过内容，并且清空了，那么，值为：''
		// const mobile = form.getFieldValue('mobile') as string | undefined
		// console.log(mobile)
		// if (mobile === undefined || mobile.trim() === '') {
		//   return mobileRef.current?.focus()
		// }

		const mobile = (form.getFieldValue('mobile') ?? '') as string
		//判断手机号是否校验成功(格式是否正确)
		const hasError = form.getFieldError('mobile').length > 0
		//文本框值为空或格式错误，文本框自动获得焦点
		if (mobile.trim() === '' || hasError) {
			return mobileRef.current?.focus()
		}
		dispatch(getCode(mobile))
		//设置倒计时时间
		setTimeLeft(5)
		// 注意：此处需要明确指定 window.serInterval 表示使用的是浏览器环境中的定时器
		//使用 window.setInterval 后，返回值才是 number 类型的数值
		timerRef.current = window.setInterval(() => {
			setTimeLeft((timeLeft) => timeLeft - 1)
		}, 1000)

		Toast.show({
			content: '验证码已发送',
			duration: 600,
		})
	}

	//1、监听定时器变化，倒计时结束清除
	useEffect(() => {
		// console.log('当前剩余时间：', timerRef)
		if (timeLeft === 0) {
			window.clearInterval(timerRef.current)
		}
	}, [timeLeft])

	//2、在组件卸载清理定时器
	useEffect(() => {
		return () => {
			window.clearInterval(timerRef.current)
		}
	}, [])

	return (
		<div className={styles.root}>
			<NavBar></NavBar>

			<div className='login-form'>
				<h2 className='title'>账号登录</h2>

				<Form
					form={form}
					onFinish={onFinish}
					validateTrigger={['onBlur']}
				>
					<Form.Item
						name='mobile'
						validateTrigger='onBlur'
						rules={[
							{ required: true, message: '请输入手机号' },
							{
								pattern: /^1[3-9]\d{9}$/,
								message: '手机号格式错误',
							},
						]}
						className='login-item'
					>
						<Input
							placeholder='请输入手机号'
							maxLength={11}
							ref={mobileRef}
						/>
					</Form.Item>

					<Form.Item
						className='login-item'
						name='code'
						rules={[{ required: true, message: '请输入验证码' }]}
						// validateTrigger='onBlur'
						extra={
							<span
								//判断是否开启定时器，没开启绑定点击事件，开启后去除
								onClick={timeLeft === 0 ? onGetCode : undefined}
								className='code-extra'
							>
								{/* 判断是否开启定时器，没开启展示发送验证码，开启展示倒计时 */}
								{timeLeft === 0
									? '发送验证码'
									: `${timeLeft}s后重新获取`}
							</span>
						}
					>
						<Input placeholder='请输入验证码' autoComplete='off' />
					</Form.Item>

					{/* noStyle 表示不提供 Form.Item 自带的样式 */}
					<Form.Item noStyle shouldUpdate>
						{() => {
							// isFieldsTouched(true) 检查是否所有字段都被操作过
							const untouched = !form.isFieldsTouched(true)
							// getFieldsError() 获取所有字段名对应的错误信息
							const hasError =
								form
									.getFieldsError()
									.filter(({ errors }) => errors.length)
									.length !== 0
							const disabled = untouched || hasError

							return (
								<Button
									block
									type='submit'
									color='primary'
									className='login-submit'
									disabled={disabled}
								>
									提交
								</Button>
							)
						}}
					</Form.Item>
				</Form>
			</div>
		</div>
	)
}

export default Login
